﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIA.Domain.Repositories;
using VIA.Integration;
using VIA.Integration.Alarms;
using VIA.Integration.Domain;
using VIA.SiMoJi.Domain.Option;
using static OpenCvSharp.Stitcher;

namespace VIA.SiMoJi.Domain.Electronics
{
    public class SafetyDoors : Safety, ISuportClearAlarm, ISuportInitialization
    {
        private bool doorAlarm1;
        private bool doorAlarm2;
        private InspectorOption _inspectorOption;
        #region 报警

        [Alarm(true, AlarmLevel.Error, "安全门1报警", Logical.Equal)]
        public bool DoorAlarm1 { get => doorAlarm1; set => NotifyAlarm(ref doorAlarm1, value); }

        [Alarm(true, AlarmLevel.Error, "安全门2报警", Logical.Equal)]
        public bool DoorAlarm2 { get => doorAlarm2; set => NotifyAlarm(ref doorAlarm2, value); }
        public Door Door1 { get; }
        public Door Door2 { get; }
        /// <summary>
        /// 门禁1继电器
        /// </summary>
        public IoPoint Door1Power { get; }
        /// <summary>
        /// 门禁2继电器
        /// </summary>
        public IoPoint Door2Power { get; }
        bool IsUseDoor => !_inspectorOption.IsIgnoreSaveDoor;
        bool IsEnabledDoorPower { get; set; }
        #endregion
        public SafetyDoors(Door door1, Door door2, IoPoint door1Power, IoPoint door2Power) : base(door1, door2)
        {
            Door1 = door1;
            Door2 = door2;
            Door1Power = door1Power;
            Door2Power = door2Power;
            this.InitalizeAlarms();
        }

        public async Task Refreshing()
        {
            Door1.IsEnabled = IsUseDoor;
            Door2.IsEnabled = IsUseDoor;
            if (IsUseDoor && IsEnabledDoorPower)
            {
                DoorAlarm1 = Door1Power.Value && !Door1.Value;
                DoorAlarm2 = Door2Power.Value && !Door2.Value;
                await Task.Delay(50);
            }
        }
        public async Task Enabled()
        {
            if (IsUseDoor)
            {
                await Task.WhenAll(Task.Run(async () =>
                {
                    DoorAlarm1 = await Enabled(Door1Power, Door1);
                }), Task.Run(async () =>
                {
                    DoorAlarm2 = await Enabled(Door2Power, Door2);
                }));
                if (!doorAlarm1 && !doorAlarm2)
                {
                    IsEnabledDoorPower = true;
                }
            }
        }
        async Task<bool> Enabled(IoPoint doorPower, Door door)
        {
            doorPower.Value = true;
            if (await Judger.Sure(() => door.Value == true, timeout: 500) == false)
            {
                return true;
            }
            return false;
        }
        public void Disabled()
        {
            if (IsUseDoor)
            {
                IsEnabledDoorPower = false;
                Door1Power.Value = false;
                Door2Power.Value = false;
            }
        }
        public void ClearAlarm()
        {
            if (IsUseDoor)
            {
                DoorAlarm1 = false;
                DoorAlarm2 = false;
            }
        }

        public Task InitializeAsync()
        {
            var optionRepository = Service.GetRequiredService<IOptionRepository>();
            optionRepository.OnSaved += Repository_OnSaved;
            _inspectorOption = optionRepository.Get<InspectorOption>();
            return Task.CompletedTask;
        }

        private void Repository_OnSaved(object sender, RecipeChangedEventArgs e)
        {
            _inspectorOption = e.NewRecipe.Get<InspectorOption>();
        }
    }
}
